package com.swak.fx.support.ui;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;

public class UISearchBar extends GridPane implements UILifecycle {

	private final String STYLE_CLASS = "ui-search-bar";
	private final String LEFT_STYLE_CLASS = "ui-search-bar_left";
	private final String TEXT_STYLE_CLASS = "ui-search-bar_text";
	private final String RIGHT_STYLE_CLASS = "ui-search-bar_right";
	private final String STYLESHEET = UI.load("css/UISearchBar.css");

	private TextField defaultTextNode;
	private UIIcon defaultLeftNode;
	private UIIcon defaultRightNode;
	private Pane rightPane;
	private String promptText = "请输入...";

	public UISearchBar() {
		this.init();
	}

	public UISearchBar(String promptText) {
		this.promptText = promptText;
		this.init();
	}

	@Override
	public void initializeParts() {
		getStyleClass().add(STYLE_CLASS);
		this.rightPane = new StackPane();
		this.defaultTextNode = new TextField();
		this.defaultLeftNode = new UIIcon(UI.Icons.SEARCH);
		this.defaultRightNode = new UIIcon(UI.Icons.REMOVE);
		this.add(this.rightPane, 3, 0);

		this.rightPane.getStyleClass().add(RIGHT_STYLE_CLASS);
		GridPane.setHgrow(this.rightPane, Priority.NEVER);
		GridPane.setVgrow(this.rightPane, Priority.ALWAYS);
		GridPane.setHalignment(this.rightPane, HPos.CENTER);
		GridPane.setValignment(this.rightPane, VPos.CENTER);
		GridPane.setMargin(this.rightPane, new Insets(0, 0, 0, 10));
	}

	@Override
	public void setupValueChangedListeners() {
		leftNodeProperty().addListener((ob, o, n) -> this.onLeftNodeChange(o, n));
		textNodeProperty().addListener((ob, o, n) -> this.onTextNodeChange(o, n));
		rightNodeProperty().addListener((ob, o, n) -> this.onRightNodeChange(o, n));
	}

	private void onLeftNodeChange(Node old, Node add) {
		if (old != null) {
			this.getChildren().remove(old);
		}
		if (add != null) {
			this.getChildren().add(add);
			add.getStyleClass().add(LEFT_STYLE_CLASS);
			GridPane.setConstraints(add, 0, 0);
			GridPane.setHgrow(add, Priority.NEVER);
			GridPane.setVgrow(add, Priority.ALWAYS);
			GridPane.setHalignment(add, HPos.CENTER);
			GridPane.setValignment(add, VPos.CENTER);
			GridPane.setMargin(add, new Insets(0, 10, 0, 0));
		}
	}

	private void onTextNodeChange(Node old, Node add) {
		if (old != null) {
			this.getChildren().remove(old);
		}
		if (add != null) {
			this.getChildren().add(add);
			add.getStyleClass().add(TEXT_STYLE_CLASS);
			GridPane.setConstraints(add, 1, 0);
			GridPane.setHgrow(add, Priority.ALWAYS);
			GridPane.setVgrow(add, Priority.ALWAYS);
			GridPane.setHalignment(add, HPos.LEFT);
			GridPane.setValignment(add, VPos.CENTER);
		}
	}

	private void onRightNodeChange(Node old, Node add) {
		if (old != null) {
			this.rightPane.getChildren().remove(old);
		}
		if (add != null) {
			this.rightPane.getChildren().add(add);
			StackPane.setAlignment(add, Pos.CENTER);
		}
	}

	@Override
	public void setupEventHandlers() {
		UILifecycle.super.setupEventHandlers();
		this.rightPane.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> {
			e.consume();
			this.clear();
		});
		this.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> {
			Node node = this.textNodeProperty().get();
			if (node != null) {
				node.setDisable(false);
				if (node instanceof TextField) {
					((TextField) node).setText("");
				}
			}
			this.rightPane.setVisible(true);
		});
	}

	@Override
	public void initializeFinish() {
		this.leftNodeProperty().set(defaultLeftNode);
		this.textNodeProperty().set(defaultTextNode);
		this.rightNodeProperty().set(defaultRightNode);
		this.clear();
	}

	public void clear() {
		Node node = this.textNodeProperty().get();
		if (node != null) {
			node.setDisable(true);
			if (node instanceof TextField) {
				((TextField) node).setText("");
				((TextField) node).setPromptText(promptText);
			}
		}
	}

	// ================================================================================
	// Overridden Methods
	// ================================================================================

	@Override
	public String getUserAgentStylesheet() {
		return STYLESHEET;
	}

	// ================================================================================
	// Properties
	// ================================================================================

	private final ObjectProperty<Node> leftNodeProperty = new SimpleObjectProperty<Node>(this, "left-node");
	private final ObjectProperty<Node> textNodeProperty = new SimpleObjectProperty<Node>(this, "text-node");
	private final ObjectProperty<Node> rightNodeProperty = new SimpleObjectProperty<Node>(this, "right-node");

	public ObjectProperty<Node> leftNodeProperty() {
		return leftNodeProperty;
	}

	public ObjectProperty<Node> textNodeProperty() {
		return textNodeProperty;
	}

	public ObjectProperty<Node> rightNodeProperty() {
		return rightNodeProperty;
	}

	public UISearchBar setLeftNode(Node node) {
		leftNodeProperty().set(node);
		return this;
	}

	public UISearchBar setRightNode(Node node) {
		rightNodeProperty().set(node);
		return this;
	}

	public UISearchBar setTextNode(Node node) {
		textNodeProperty().set(node);
		return this;
	}
}